﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

public partial class ExpressionTree表达式树_表达式赋值与获取值 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Test();
    }


    public void Test()
    {
        M_Ask ask = new M_Ask();

        int result = GetIntValue<M_Ask>(ask, "Id");

      var fun=   BuildGetPropertyAction<M_Ask, int>(ask.GetType().GetProperty("Id"));
 
        Get一个固定对像id(ask, "Id");



    }

    public void 别人创建表达式的方法()
    {
        //var r = ints.Where(i => i =5&&i==6);   
        // 要实现的表达式  
        // 创建参数 i  
        // var parameter =Expression.Parameter(typeof(int), "i");

        // 创建常量5  
        //var constant =Expression.Constant(5);

        //// 创建比较表达式 i = 5  
        //var bin = Expression.Equal(parameter, constant);

        //for(int i=6;i<7;i++)
        //     bin = Expression.Or(bin, Expression.Equal(parameter, Expression.Constant(i)));
        //// 获取Lambda表达式  
        //var lambda = Expression.Lambda<Func<int, bool>>(bin, parameter);

        //// 测试 通过 Compile 方法获取 Delegate  
        //var _r = ints.Where(lambda.Compile());
        //            foreach (var v in _r)
        //                Response.Write(v+"<br>");

        //显示：
    }



    Func<int> fun;
    int code;

    /// <summary>
    /// 获取
    /// </summary>
    /// <param name="o">对像</param>
    /// <param name="name">名称</param>
    /// <returns></returns>
    public int Get一个固定对像id(object o, string name)
    {

        // System.Linq.Expressions.Expression<Func<int>> xp = p => ((M_Ask)p).Id;
        //http://technet.microsoft.com/zh-cn/library/bb341554(v=vs.100)
        //设置参数  ((M_Ask)p).Id 表达式
        System.Linq.Expressions.Expression numParam = Expression.Property(
            //创建常量
            Expression.Constant(o),
            //创建变量
            name
            );

        //参数
        var param = Expression.Parameter(o.GetType(), "p");


        //返回结果
        Func<int> result = Expression.Lambda<Func<int>>(numParam).Compile();
        fun = result;
        //Expression<Func<int, bool>> exprTree = num => num < 5;
        //ParameterExpression numParam = Expression.Parameter(typeof(int), "num");
        //ConstantExpression five = Expression.Constant(5, typeof(int));
        //BinaryExpression numLessThanFive = Expression.LessThan(numParam, five);
        //Expression<Func<int, bool>> lambda1 =
        //Expression.Lambda<Func<int, bool>>(
        //numLessThanFive,
        //new ParameterExpression[] { numParam });

        M_Ask ask = new M_Ask();

        //
        return 0;
    }

 
    int codeint;

    public int GetIntValue<T>(object o, string name)
    {

        //http://blog.csdn.net/fuadam/article/details/2958863
        Func<T, int> funint;
        if (codeint == 0) {

            var type = o.GetType();
            var p = type.GetProperty(name);
            //lambda的参数u
            var param_u = Expression.Parameter(type, "p");
            //lambda的方法体 u.Age
            var pGetter = Expression.Property(param_u, p);
            //编译lambda
            var getAge = Expression.Lambda<Func<T, int>>(pGetter, param_u).Compile();
            //
            if (getAge.GetHashCode() != codeint)
            {
                codeint = getAge.GetHashCode();
                funint = getAge;
            }
        }

        return 0;


    }

    /// <summary>
    /// 强类型动态传值
    /// </summary>
    /// <typeparam name="TInstance"></typeparam>
    /// <typeparam name="TProperty"></typeparam>
    /// <param name="propertyInfo"></param>
    /// <returns></returns>
    public static Action<TInstance, TProperty> BuildSetPropertyAction<TInstance, TProperty>(System.Reflection.PropertyInfo propertyInfo)
    {
        var instanceParam = Expression.Parameter(typeof(TInstance), "instance");
        var valueParam = Expression.Parameter(typeof(TProperty), "value");
        //instance.Property
        var propertyProperty = Expression.Property(instanceParam, propertyInfo);
        //instance.Property = value 这名话是重点
        var assignExpression = Expression.Assign(propertyProperty, valueParam);
        var lambdaExpression = Expression.Lambda<Action<TInstance, TProperty>>(assignExpression, instanceParam, valueParam);
        return lambdaExpression.Compile();
    }

    /// <summary>
    /// 强类型动态取值
    /// </summary>
    /// <typeparam name="TInstance"></typeparam>
    /// <typeparam name="TProperty"></typeparam>
    /// <param name="propertyInfo"></param>
    /// <returns></returns>
    public static Func<TInstance, TProperty> BuildGetPropertyAction<TInstance, TProperty>(System.Reflection.PropertyInfo propertyInfo)
    {
        var instanceParam = Expression.Parameter(typeof(TInstance), "instance");
        var valueParam = Expression.Parameter(typeof(TProperty), "value");
        //instance.Property ,表示一个取值
        var propertyProperty = Expression.Property(instanceParam, propertyInfo);

        var lambdaExpression = Expression.Lambda<Func<TInstance, TProperty>>(instanceParam, valueParam);
        return lambdaExpression.Compile();
    }
}